package handler

import (
	"bufio"
	"bytes"
	"encoding/csv"
	"flare-admin/db/sqlc/ddos"
	"flare-admin/ecode"
	"flare-admin/http/model"
	"flare-admin/http/model/k8sresource"
	"flare-admin/http/request"
	"flare-admin/service"
	"flare-admin/service/dto"
	"flare-admin/service/dto/micro"
	"fmt"
	"io"
	"io/ioutil"
	"math/rand"
	"net/netip"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

func HelloWorld(ctx *gin.Context) (any, error) {
	return "Hello World", nil
}

func GetAllPattern(ctx *gin.Context) (any, error) {
	return service.Svc.GetAllPattern(ctx)
}

func AddPattern(ctx *gin.Context) (any, error) {
	req := request.AddPatternRequest{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[AddPatternResult] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.AddPattern(ctx, micro.AddPatternRequest2DTO(&req))
}

func GetAllPatternMatchResult(ctx *gin.Context) (any, error) {
	resultDao, err := service.Svc.GetAllPatternMatchResult(ctx)
	if err != nil {
		return []model.PatternResultModel{}, err
	}
	result := make([]model.PatternResultModel, 0)
	for _, each := range resultDao {
		result = append(result, model.PatternResultModel{
			PatternName:    each.PatternName.String,
			CybertwinLabel: each.CybertwinLabel,
			PatternGraph:   string(each.GraphData),
			InvokeTime:     each.InvokeTime.Time.Format(time.DateTime),
			AnalyseTime:    each.AnalyseTime.Time.Format(time.DateTime),
		})
	}
	return result, nil
}

// AddPatternResult 添加匹配结果
//
//	pattern_id: int
//	cybertwin_id: int
//	cybertwin_label: string
func AddPatternResult(ctx *gin.Context) (any, error) {
	req := request.PatternMatchResultRequest{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[AddPatternResult] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	d, err := micro.PatternMatchResultRequest2DTO(&req)
	if err != nil {
		logrus.Errorf("[AddPatternResult] - [PatternMatchResultRequest2DTO] - failed to convert request to DTO: %v", err)
		return nil, err
	}
	return service.Svc.AddPatternMatchResult(ctx, d)
}

func GetAllReverseShConfig(ctx *gin.Context) (any, error) {
	return service.Svc.GetAllReverseSgConfig(ctx)
}

func AddReverseConfig(ctx *gin.Context) (any, error) {
	req := struct {
		NodeIP string `json:"node_ip"`
	}{}
	resp := struct {
		Message string `json:"message"`
	}{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[AddReverseConfig] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	// 校验ip地址合法性
	if _, err := netip.ParseAddr(req.NodeIP); err != nil {
		logrus.Errorf("[AddReverseConfig] - [ParseAddr] - failed to parse ip: %v", err)
		resp.Message = "ip地址不合法"
		return &resp, ecode.ErrRequestParam
	}

	res, err := service.Svc.AddReverseShConfig(ctx, req.NodeIP)
	if err != nil {
		resp.Message = "内部错误"
	} else if !res {
		resp.Message = "ip地址已存在"
	} else {
		resp.Message = "添加成功"
	}

	return &resp, nil
}

func DeleteReverseConfig(ctx *gin.Context) (any, error) {
	// TODO: 删除代码暂不开发
	return nil, nil
}

func EnableReverseSh(ctx *gin.Context) (any, error) {
	req := struct {
		NodeIP string `json:"node_ip"`
		Enable bool   `json:"enable"`
	}{}
	resp := struct {
		Message string `json:"message"`
	}{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[EnableReverseSh] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	// 校验ip地址合法性
	if _, err := netip.ParseAddr(req.NodeIP); err != nil {
		logrus.Errorf("[EnableReverseSh] - [ParseAddr] - failed to parse ip: %v", err)
		resp.Message = "ip地址不合法"
		return &resp, ecode.ErrRequestParam
	}

	if err := service.Svc.EnableReverseShPluginInNode(ctx, req.NodeIP, req.Enable); err != nil {
		logrus.Errorf("[EnableReverseSh] - [EnableReverseShPluginInNode] - failed to enable(%v) plugin in node: %v", req.Enable, err)
		return nil, err
	}
	if req.Enable {

		resp.Message = "开启插件成功"
	} else {
		resp.Message = "关闭插件成功"
	}

	return &resp, nil
}

func UploadReverseShRecord(ctx *gin.Context) (any, error) {
	req := struct {
		Ctids           []uint64 `json:"ctids"`      // cybertwin的ID列表
		Message         string   `json:"message"`    // 反向shell的消息内容
		SyscallFuncName string   `json:"syscall"`    // 系统调用函数名
		NodeName        string   `json:"node_name"`  // 节点名称
		EventTime       string   `json:"event_time"` // 事件发生时间，格式为RFC3339
	}{}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[UploadReverseShRecord] -绑定参数错误")
		return nil, ecode.ErrRequestParam
	}
	if len(req.Ctids) == 0 {
		logrus.Errorf("[UploadReverseShRecord] - [Ctids] - ctids is empty")
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Security.ReverseSh.UploadReverseShRecord(ctx, req.Ctids, req.Message, req.SyscallFuncName, req.NodeName, req.EventTime)
}

func GetAllReverseShAuditResults(ctx *gin.Context) (any, error) {

	dtos, err := service.Svc.Security.ReverseSh.GetAllReverseShAuditResults(ctx)
	if err != nil {
		logrus.Errorf("[GetAllReverseShAuditResults] - failed to get all reverse shell audit results: %v", err)
		return nil, ecode.ErrDBExecution
	}
	results := make([]model.ReverseShAuditResult, 0, len(dtos))
	for _, dto := range dtos {
		results = append(results, model.ReverseShAuditResult{
			ID:          dto.ID,
			CybertwinID: dto.CybertwinID,
			Syscall:     dto.Syscall,
			NodeName:    dto.NodeName,
			EventTime:   dto.EventTime.Format(time.RFC3339),
		})
	}
	return results, nil
}

func GetAllCluster(ctx *gin.Context) (any, error) {
	req := struct {
		Type string `form:"type" json:"type"`
	}{}
	if err := ctx.ShouldBindQuery(&req); err != nil {
		logrus.Errorf("[GetAllCluster] - [ShouldBindQuery] - failed to bind query: %v", err)
		return nil, ecode.ErrRequestParam
	}
	//if err := ctx.ShouldBindJSON(&req); err != nil {
	//	logrus.Errorf("[GetAllCluster] - [ShouldBindJSON] - failed to bind json: %v", err)
	//	return nil, ecode.ErrRequestParam
	//}
	// type类型只能为"core"和"edge"
	if req.Type != "core" && req.Type != "edge" {
		logrus.Errorf("[GetAllCluster] - [Type] - invalid type: %s", req.Type)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.GetAllClusterByType(ctx, req.Type)
}

func AddClusterConfig(ctx *gin.Context) (any, error) {
	req := struct {
		Name              string `json:"name"`
		KubeConfigContent string `json:"kube_config_content"` // k8s集群的kubeconfig内容
		ClusterType       string `json:"cluster_type"`        // 集群类型，core或edge
	}{}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[AddClusterConfig] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if req.Name == "" || req.KubeConfigContent == "" {
		logrus.Errorf("[AddClusterConfig] - [Name/KubeConfigContent] - name or kubeconfig content is empty")
		return nil, ecode.ErrRequestParam
	}
	if res, err := service.Svc.Cluster.AddClusterConfig(ctx, req.Name, req.KubeConfigContent, req.ClusterType); err != nil {
		return nil, err
	} else {
		return res, nil
	}

}

func DeleteClusterConfig(ctx *gin.Context) (any, error) {
	req := struct {
		Name        string `json:"name"`
		ClusterType string `json:"cluster_type"` // 集群类型，core或edge
	}{}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[DeleteClusterConfig] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if req.Name == "" {
		logrus.Errorf("[DeleteClusterConfig] - [Name] - name is empty")
		return nil, ecode.ErrRequestParam
	}
	if resp, err := service.Svc.Cluster.DeleteClusterConfig(ctx, req.ClusterType, req.Name); err != nil {
		logrus.Errorf("[DeleteClusterConfig] - [DeleteClusterConfig] - failed to delete cluster config: %v", err)
		return nil, err
	} else {
		return resp, nil
	}

}

func GetClusterMetaInfoByID(ctx *gin.Context) (any, error) {
	clusterIDStr := ctx.Param("cluster_id")
	if clusterIDStr == "" {
		return nil, ecode.ErrRequestParam
	}
	clusterID, err := strconv.ParseInt(clusterIDStr, 10, 32)
	if err != nil {
		logrus.Errorf("[GetClusterMetaInfoByID] - [ParseInt] - failed to parse cluster_id: %v", err)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.GetClusterByID(ctx, int(clusterID))
}

func GetClusterResourceByID(ctx *gin.Context) (any, error) {
	clusterIDStr := ctx.Param("cluster_id")
	if clusterIDStr == "" {
		return nil, ecode.ErrRequestParam
	}
	clusterID, err := strconv.ParseInt(clusterIDStr, 10, 32)
	if err != nil {
		logrus.Errorf("[GetClusterResourceByID] - [ParseInt] - failed to parse cluster_id: %v", err)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.GetClusterResourceByID(ctx, int(clusterID))
}

// GetClusterNodesByID 获取集群节点信息
func GetClusterNodesByID(ctx *gin.Context) (any, error) {
	clusterIDStr := ctx.Param("cluster_id")
	if clusterIDStr == "" {
		return nil, ecode.ErrRequestParam
	}
	clusterID, err := strconv.ParseInt(clusterIDStr, 10, 32)
	if err != nil {
		logrus.Errorf("[GetClusterNodesByID] - [ParseInt] - failed to parse cluster_id: %v", err)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.GetClusterNodesByID(ctx, int(clusterID))
}

// GetClusterNamespacesByID 获取集群命名空间信息
func GetClusterNamespacesByID(ctx *gin.Context) (any, error) {
	clusterIDStr := ctx.Param("cluster_id")
	if clusterIDStr == "" {
		return nil, ecode.ErrRequestParam
	}
	clusterID, err := strconv.ParseInt(clusterIDStr, 10, 32)
	if err != nil {
		logrus.Errorf("[GetClusterNamespacesByID] - [ParseInt] - failed to parse cluster_id: %v", err)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.GetClusterNamespacesByID(ctx, int(clusterID))
}

// handler/ddos.go
func GetAllDDoSFlows(ctx *gin.Context) (any, error) {
	// 从数据库获取所有DDoS流量数据
	dbFlows, err := service.Svc.GetAllDDoSFlowsFromDB(ctx)
	if err != nil {
		logrus.Errorf("[GetAllDDoSFlows] - failed to get ddos flows from database: %v", err)
		// 如果数据库查询失败，返回空数组而不是错误，保持API的稳定性
		return []model.DDoSFlow{}, nil
	}

	// 转换为HTTP模型
	flows := dto.DDoSFlowsDB2Model(dbFlows)
	return flows, nil
}

// AddDDoSFlow 添加DDoS流量数据
func AddDDoSFlow(ctx *gin.Context) (any, error) {
	req := request.DDoSFlowRequest{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		// 记录更详细的错误日志，包括具体的请求体内容
		reqBody, _ := ctx.GetRawData()
		ctx.Request.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody)) // 重置请求体以便后续处理
		logrus.Errorf("[AddDDoSFlow] - [ShouldBindJSON] - failed to bind json: %v, request body: %s", err, string(reqBody))

		// 返回更详细的错误信息给客户端
		detailedErr := struct {
			Code    int    `json:"code"`
			Message string `json:"message"`
			Details string `json:"details,omitempty"`
		}{}
		detailedErr.Code = ecode.ErrRequestParam.Code
		detailedErr.Message = ecode.ErrRequestParam.Message
		detailedErr.Details = fmt.Sprintf("参数验证失败: %v", err)

		return detailedErr, nil
	}

	// 转换为DTO
	flowDTO := dto.DDoSFlowRequest2DTO(&req)

	// 调用service层添加数据
	id, err := service.Svc.AddDDoSFlow(ctx, flowDTO)
	if err != nil {
		logrus.Errorf("[AddDDoSFlow] - failed to add ddos flow: %v", err)
		return nil, err
	}

	resp := struct {
		Message string `json:"message"`
		ID      int32  `json:"id"`
	}{
		Message: "DDoS流量数据添加成功",
		ID:      id,
	}
	return &resp, nil
}

// AddDDoSFlowsBatch 批量添加DDoS流量数据
func AddDDoSFlowsBatch(ctx *gin.Context) (any, error) {
	req := request.DDoSFlowsBatchRequest{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[AddDDoSFlowsBatch] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}

	// 转换为DTO
	var flowsDTO []ddos.InsertDDoSFlowParams
	for _, flow := range req.Flows {
		flowsDTO = append(flowsDTO, dto.DDoSFlowRequest2DTO(&flow))
	}

	// 调用service层批量添加数据
	err := service.Svc.AddDDoSFlowsBatch(ctx, flowsDTO)
	if err != nil {
		logrus.Errorf("[AddDDoSFlowsBatch] - failed to add ddos flows batch: %v", err)
		return nil, err
	}

	resp := struct {
		Message string `json:"message"`
		Count   int    `json:"count"`
	}{
		Message: "批量添加DDoS流量数据成功",
		Count:   len(req.Flows),
	}
	return &resp, nil
}

// GetDDoSFlowsByType 根据流量类型获取DDoS流量数据
func GetDDoSFlowsByType(ctx *gin.Context) (any, error) {
	flowType := ctx.Query("flow_type")
	if flowType == "" {
		logrus.Errorf("[GetDDoSFlowsByType] - flow_type parameter is required")
		return nil, ecode.ErrRequestParam
	}

	dbFlows, err := service.Svc.GetDDoSFlowsByType(ctx, flowType)
	if err != nil {
		logrus.Errorf("[GetDDoSFlowsByType] - failed to get ddos flows by type: %v", err)
		return nil, err
	}

	flows := dto.DDoSFlowsDB2Model(dbFlows)
	return flows, nil
}

// GetDDoSFlowsByIP 根据IP获取DDoS流量数据
func GetDDoSFlowsByIP(ctx *gin.Context) (any, error) {
	ip := ctx.Query("ip")
	if ip == "" {
		logrus.Errorf("[GetDDoSFlowsByIP] - ip parameter is required")
		return nil, ecode.ErrRequestParam
	}

	dbFlows, err := service.Svc.GetDDoSFlowsByIP(ctx, ip)
	if err != nil {
		logrus.Errorf("[GetDDoSFlowsByIP] - failed to get ddos flows by ip: %v", err)
		return nil, err
	}

	flows := dto.DDoSFlowsDB2Model(dbFlows)
	return flows, nil
}

// InitializeDDoSFlowsData 初始化DDoS流量数据到数据库
func InitializeDDoSFlowsData(ctx *gin.Context) (any, error) {
	err := service.Svc.InitializeDDoSFlowsData(ctx)
	if err != nil {
		logrus.Errorf("[InitializeDDoSFlowsData] - failed to initialize ddos flows data: %v", err)
		return nil, err
	}

	resp := struct {
		Message string `json:"message"`
	}{
		Message: "DDoS流量数据初始化成功",
	}
	return &resp, nil
}

// GetDDoSFlowSyncStatus 获取DDoS流量同步服务状态
func GetDDoSFlowSyncStatus(ctx *gin.Context) (any, error) {
	syncService := service.GetDDoSFlowSyncService()
	if syncService == nil {
		return map[string]interface{}{
			"status":  "not_initialized",
			"message": "同步服务未初始化",
		}, nil
	}

	stats := syncService.GetStats()
	return stats, nil
}

func GetAllZtrustEvents(ctx *gin.Context) (any, error) {
	return service.Svc.GetAllZtrustEvents(ctx)
}

func GetCtZtrustEvents(ctx *gin.Context) (any, error) {
	var (
		cybertwinIDStr string
	)
	cybertwinIDStr = ctx.Param("cybertwin_id")
	cybertwinID, err := strconv.ParseUint(cybertwinIDStr, 10, 64)
	if err != nil {
		logrus.Errorf("[GetCtZtrustEvents] - [ParseUint] - failed to parse cybertwin_id: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if cybertwinID == 0 || (cybertwinID&(1<<63)) != 0 {
		logrus.Errorf("[GetCtZtrustEvents] - invalid cybertwin_id (%d)", cybertwinID)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.GetCtZtrustEvents(ctx, cybertwinIDStr)
}

func GetAllZtrustScores(ctx *gin.Context) (any, error) {
	return service.Svc.GetAllZtrustScores(ctx)
}

func GetAllZtrustAccessEvents(ctx *gin.Context) (any, error) {
	return service.Svc.GetAllZtrustAccessEvents(ctx)
}

func LoadClusterConfigFromDB(ctx *gin.Context) (any, error) {
	var (
		clusterIDStr string
	)
	clusterIDStr = ctx.Param("cluster_id")
	clusterID, err := strconv.ParseInt(clusterIDStr, 10, 32)
	if err != nil {
		logrus.Errorf("[LoadClusterConfigFromDB] - [ParseInt] - failed to parse cluster_id: %v", err)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.LoadClusterConfigFromDB(ctx, int32(clusterID))
}

func GetAllPodsInNamespace(ctx *gin.Context) (any, error) {
	var (
		namespace string
		clusterID string
	)
	namespace = ctx.Param("namespace")
	if namespace == "" {
		logrus.Errorf("[GetAllPodsInNamespace] - namespace is empty")
		return nil, ecode.ErrRequestParam
	}
	clusterID = ctx.Param("cluster_id")
	if clusterID == "" {
		logrus.Errorf("[GetAllPodsInNamespace] - cluster_id is empty")
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.Pod.ListPodsByClusterID(ctx, clusterID, namespace)
}

func CreatePodInClusterID(ctx *gin.Context) (any, error) {
	var (
		clusterIDStr string
		podInfo      k8sresource.PodInfo
	)

	clusterIDStr = ctx.Param("cluster_id")
	clusterID, err := strconv.ParseInt(clusterIDStr, 10, 32)
	if err != nil {
		logrus.Errorf("[CreatePodInClusterID] - [ParseInt] - failed to parse cluster_id: %v", err)
		return nil, ecode.ErrRequestParam
	}

	if err = ctx.ShouldBindJSON(&podInfo); err != nil {
		logrus.Errorf("[CreatePodInClusterID] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.Pod.CreatePodInClusterID(ctx, int(clusterID), podInfo.MetaData.Namespace, podInfo)
}

func CreatePodByYaml(ctx *gin.Context) (any, error) {
	req := struct {
		ClusterID   int    `json:"clusterId"`
		YAMLContent string `json:"yaml"` // Pod的YAML内容
	}{}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[CreatePodByYaml] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if req.ClusterID <= 0 {
		logrus.Errorf("[CreatePodByYaml] - [ClusterID] - clusterId is invalid: %d", req.ClusterID)
		return nil, ecode.ErrRequestParam
	}
	if req.YAMLContent == "" {
		logrus.Errorf("[CreatePodByYaml] - [YAMLContent] - YAML content is empty")
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.Pod.CreatePodByYaml(ctx, req.ClusterID, req.YAMLContent)
}

func DeletePodInClusterID(ctx *gin.Context) (any, error) {
	req := struct {
		PodName   string `json:"podName"`
		ClusterID int    `json:"clusterId"`
		Namespace string `json:"namespace"`
	}{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[DeletePodInClusterID] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if req.PodName == "" || req.Namespace == "" {
		logrus.Errorf("[DeletePodInClusterID] - [PodName/Namespace] - podName or namespace is empty")
		return nil, ecode.ErrRequestParam
	}
	if req.ClusterID <= 0 {
		logrus.Errorf("[DeletePodInClusterID] - [ClusterID] - clusterId is invalid: %d", req.ClusterID)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.DeletePodInClusterID(ctx, req.ClusterID, req.Namespace, req.PodName)
}

func GetAllDeploymentsInNamespace(ctx *gin.Context) (any, error) {
	var (
		namespace string
		clusterID string
	)
	namespace = ctx.Param("namespace")
	if namespace == "" {
		logrus.Errorf("[GetAllDeploymentsInNamespace] - namespace is empty")
		return nil, ecode.ErrRequestParam
	}
	clusterID = ctx.Param("cluster_id")
	if clusterID == "" {
		logrus.Errorf("[GetAllDeploymentsInNamespace] - cluster_id is empty")
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.Deployment.ListDeploymentsByClusterID(ctx, clusterID, namespace)
}

func CreateDeploymentByYaml(ctx *gin.Context) (any, error) {
	req := struct {
		ClusterID   int    `json:"clusterId"`
		YAMLContent string `json:"yaml"` // Deployment的YAML内容
	}{}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[CreateDeploymentByYaml] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if req.ClusterID <= 0 {
		logrus.Errorf("[CreateDeploymentByYaml] - [ClusterID] - clusterId is invalid: %d", req.ClusterID)
		return nil, ecode.ErrRequestParam
	}
	if req.YAMLContent == "" {
		logrus.Errorf("[CreateDeploymentByYaml] - [YAMLContent] - YAML content is empty")
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.CreateDeploymentByYaml(ctx, req.ClusterID, req.YAMLContent)
}

func DeleteDeploymentInClusterID(ctx *gin.Context) (any, error) {
	req := struct {
		DeploymentName string `json:"deploymentName"`
		ClusterID      int    `json:"clusterId"`
		Namespace      string `json:"namespace"`
	}{}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		logrus.Errorf("[DeleteDeploymentInClusterID] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}
	if req.DeploymentName == "" || req.Namespace == "" {
		logrus.Errorf("[DeleteDeploymentInClusterID] - [DeploymentName/Namespace] - deploymentName or namespace is empty")
		return nil, ecode.ErrRequestParam
	}
	if req.ClusterID <= 0 {
		logrus.Errorf("[DeleteDeploymentInClusterID] - [ClusterID] - clusterId is invalid: %d", req.ClusterID)
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.DeleteDeploymentInClusterID(ctx, req.ClusterID, req.Namespace, req.DeploymentName)
}

func GetRangedLatencyInfoIn(ctx *gin.Context) (any, error) {
	// path variable
	startTime, endTime := ctx.Query("start_time"), ctx.Query("end_time")
	clusterId := ctx.Param("cluster_id")
	if clusterId == "" {
		logrus.Errorf("[GetRangedLatencyInfoIn] - clusterid: %s, startTime: %s, endTime: %s", clusterId, startTime, endTime)
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.Schedule.GetLatencyInfo(ctx, clusterId, startTime, endTime)
}

func GetRangedLatencyInfoPair(ctx *gin.Context) (any, error) {
	// path variable
	startTime, endTime := ctx.Query("start_time"), ctx.Query("end_time")
	node1, node2 := ctx.Query("node1"), ctx.Query("node2")
	if node1 == "" || node2 == "" {
		logrus.Errorf("[GetRangedLatencyInfoPair] - node1: %s, node2: %s", node1, node2)
		return nil, ecode.ErrRequestParam
	}

	clusterId := ctx.Param("cluster_id")
	if clusterId == "" {
		logrus.Errorf("[GetRangedLatencyInfoPair] - clusterID: %s, startTime: %s, endTime: %s", clusterId, startTime, endTime)
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.Schedule.GetLatencyInfoPair(ctx, clusterId, node1, node2, startTime, endTime)
}

// SimulateAttack 模拟攻击接口，从CSV文件读取5条数据并批量插入数据库
func AddPodGroupSchedulingRecord(ctx *gin.Context) (any, error) {
	req := &request.SchedulingRecordRequest{}
	if err := ctx.ShouldBindJSON(req); err != nil {
		logrus.Errorf("[AddPodGroupSchedulingRecord] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}

	param := ctx.Param("cluster_id")
	if param == "" {
		logrus.Errorf("[AddPodGroupSchedulingRecord] - 没有指定cluster_id")
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.Schedule.AddPodGroupSchedulingRecord(ctx, req, param)
}

func UpdatePodGroupSchedulingRecord(ctx *gin.Context) (any, error) {
	req := &request.SchedulingRecordRequest{}
	if err := ctx.ShouldBindJSON(req); err != nil {
		logrus.Errorf("[AddPodGroupSchedulingRecord] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}

	param := ctx.Param("cluster_id")
	if param == "" {
		logrus.Errorf("[AddPodGroupSchedulingRecord] - 没有指定cluster_id")
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.Schedule.UpdatePodGroupSchedulingRecord(ctx, req, param)
}

// UpdateSchedulingRecordStatus 更新调度记录状态, 由于修改内容仅一个字段，因此这里临时parse一下就好
func UpdateSchedulingRecordStatus(ctx *gin.Context) (any, error) {
	req := &struct {
		Status    string `json:"status"`
		Name      string `json:"name"`
		Namespace string `json:"namespace"`
		UID       string `json:"uid"`
	}{}

	if err := ctx.ShouldBindJSON(req); err != nil {
		logrus.Errorf("[UpdateSchedulingRecordStatus] - [ShouldBindJSON] - failed to bind json: %v", err)
		return nil, ecode.ErrRequestParam
	}

	clusterID := ctx.Param("cluster_id")
	if clusterID == "" {
		logrus.Errorf("[UpdateSchedulingRecordStatus] - 没有指定cluster_id")
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.Schedule.UpdatePodGroupSchedulingRecordStatus(ctx,
		req.Name, req.Namespace,
		req.Status, clusterID, req.UID,
	)
}

func GetAllPodGroupSchedulingRecords(ctx *gin.Context) (any, error) {
	clusterID := ctx.Param("cluster_id")
	if clusterID == "" {
		logrus.Errorf("[GetAllPodGroupSchedulingRecords] - 没有指定cluster_id")
		return nil, ecode.ErrRequestParam
	}
	return service.Svc.Cluster.Schedule.GetAllPodGroupSchedulingRecords(ctx, clusterID)
}

func GetPodGroupSchedulingRecord(ctx *gin.Context) (any, error) {
	clusterID, namespace, name, uid := ctx.Param("cluster_id"), ctx.Param("namespace"), ctx.Param("name"), ctx.Param("uid")

	if clusterID == "" || namespace == "" || name == "" || uid == "" {
		logrus.Errorf("[GetPodGroupSchedulingRecord] - 参数错误, cluster_id: %s, namespace: %s, name: %s, uid: %s", clusterID, namespace, name, uid)
		return nil, ecode.ErrRequestParam
	}

	return service.Svc.Cluster.Schedule.GetSingleRecord(ctx, clusterID, namespace, name, uid)

}

// SimulateAttack 模拟攻击接口，返回一条攻击流量
func SimulateAttack(ctx *gin.Context) (any, error) {
	// CSV文件路径
	csvFilePath := filepath.Join("static", "ddos-attack-data", "ddos_attack_flow.csv")

	// 打开CSV文件
	file, err := os.Open(csvFilePath)
	if err != nil {
		logrus.Errorf("[SimulateAttack] - failed to open CSV file: %v", err)
		return nil, fmt.Errorf("failed to open CSV file: %v", err)
	}
	defer file.Close()

	// 读取CSV文件内容
	reader := csv.NewReader(bufio.NewReader(file))
	var allRecords [][]string

	// 跳过标题行
	_, err = reader.Read()
	if err != nil {
		logrus.Errorf("[SimulateAttack] - failed to read CSV header: %v", err)
		return nil, fmt.Errorf("failed to read CSV header: %v", err)
	}

	// 读取所有数据行
	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		}
		if err != nil {
			logrus.Errorf("[SimulateAttack] - failed to read CSV record: %v", err)
			continue
		}
		allRecords = append(allRecords, record)
	}

	// 检查是否有足够的数据
	if len(allRecords) < 5 {
		logrus.Errorf("[SimulateAttack] - not enough data in CSV file, need 5 records but got %d", len(allRecords))
		return nil, fmt.Errorf("not enough data in CSV file")
	}

	// 随机选择5条数据
	selectedRecords := make([][]string, 5)
	usedIndices := make(map[int]bool)
	for i := 0; i < 5; i++ {
		var randomIndex int
		for {
			randomIndex = rand.Intn(len(allRecords))
			if !usedIndices[randomIndex] {
				usedIndices[randomIndex] = true
				break
			}
		}
		selectedRecords[i] = allRecords[randomIndex]
	}

	// 处理并准备数据
	var flows []model.DDoSFlow
	var flowRequests []request.DDoSFlowRequest
	currentTime := time.Now()

	for _, record := range selectedRecords {
		// 解析CSV数据到Features
		features := parseCSVToFeatures(record)

		// 生成10.0.x.x格式的随机IP
		ip := fmt.Sprintf("10.0.4.%d", rand.Intn(255))

		// 设置流量类型（从CSV的Label字段获取）
		flowType := "未知攻击"
		if len(record) > 27 {
			flowType = record[27] // Label字段
		}

		// 创建model.DDoSFlow
		flow := model.DDoSFlow{
			IP:           ip,
			Protocol:     features.Protocol,
			FlowDuration: features.FlowDuration,
			FwdPackets:   features.TotalFwdPackets,
			FlowType:     flowType,
			Time:         currentTime,
			Features:     features,
		}
		flows = append(flows, flow)

		// 创建request.DDoSFlowRequest用于数据库插入
		flowRequest := request.DDoSFlowRequest{
			IP:           ip,
			Protocol:     features.Protocol,
			FlowDuration: features.FlowDuration,
			FwdPackets:   features.TotalFwdPackets,
			FlowType:     flowType,
			Time:         currentTime,
			Features: request.FeaturesRequest{
				Protocol:              features.Protocol,
				FlowDuration:          features.FlowDuration,
				TotalFwdPackets:       features.TotalFwdPackets,
				TotalBackwardPackets:  features.TotalBackwardPackets,
				FwdPacketsLengthTotal: features.FwdPacketsLengthTotal,
				FwdPacketLengthMax:    features.FwdPacketLengthMax,
				FwdPacketLengthMin:    features.FwdPacketLengthMin,
				FwdPacketLengthStd:    features.FwdPacketLengthStd,
				BwdPacketLengthMax:    features.BwdPacketLengthMax,
				BwdPacketLengthMin:    features.BwdPacketLengthMin,
				FlowIATMean:           features.FlowIATMean,
				FlowIATMin:            features.FlowIATMin,
				BwdIATMean:            features.BwdIATMean,
				BwdIATMin:             features.BwdIATMin,
				FwdPSHFlags:           features.FwdPSHFlags,
				FwdHeaderLength:       features.FwdHeaderLength,
				BwdHeaderLength:       features.BwdHeaderLength,
				BwdPacketsPerSecond:   features.BwdPacketsPerSecond,
				SYNFlagCount:          features.SYNFlagCount,
				URGFlagCount:          features.URGFlagCount,
				CWEFlagCount:          features.CWEFlagCount,
				DownUpRatio:           features.DownUpRatio,
				InitFwdWinBytes:       features.InitFwdWinBytes,
				InitBwdWinBytes:       features.InitBwdWinBytes,
				ActiveMean:            features.ActiveMean,
				ActiveStd:             features.ActiveStd,
				IdleStd:               features.IdleStd,
			},
		}
		flowRequests = append(flowRequests, flowRequest)
	}

	// 转换为DTO并批量插入数据库
	var flowsDTO []ddos.InsertDDoSFlowParams
	for _, flowReq := range flowRequests {
		flowsDTO = append(flowsDTO, dto.DDoSFlowRequest2DTO(&flowReq))
	}

	// 批量插入数据库
	err = service.Svc.AddDDoSFlowsBatch(ctx, flowsDTO)
	if err != nil {
		logrus.Errorf("[SimulateAttack] - failed to insert DDoS flows into database: %v", err)
		// 即使插入失败，也返回数据供前端显示
	}

	// 返回5条数据，前端可以一条一条显示
	return flows, nil
}

// parseCSVToFeatures 将CSV记录解析为Features结构体
func parseCSVToFeatures(record []string) model.Features {
	features := model.Features{}

	// 安全地解析CSV字段，防止索引越界
	parseInt := func(idx int) int {
		if idx >= len(record) || record[idx] == "" {
			return 0
		}
		val, err := strconv.Atoi(strings.TrimSpace(record[idx]))
		if err != nil {
			return 0
		}
		return val
	}

	parseFloat := func(idx int) float64 {
		if idx >= len(record) || record[idx] == "" {
			return 0.0
		}
		val, err := strconv.ParseFloat(strings.TrimSpace(record[idx]), 64)
		if err != nil {
			return 0.0
		}
		return val
	}

	// 根据CSV字段顺序解析数据
	// 0: Protocol
	// 1: Flow Duration
	// 2: Total Fwd Packets
	// 3: Total Backward Packets
	// 4: Total Length of Fwd Packets
	// 5: Fwd Packet Length Max
	// 6: Fwd Packet Length Min
	// 7: Fwd Packet Length Std
	// 8: Bwd Packet Length Max
	// 9: Bwd Packet Length Min
	// 10: Flow IAT Mean
	// 11: Flow IAT Min
	// 12: Bwd IAT Mean
	// 13: Bwd IAT Min
	// 14: Fwd PSH Flags
	// 15: Fwd Header Length
	// 16: Bwd Header Length
	// 17: Bwd Packets/s
	// 18: SYN Flag Count
	// 19: URG Flag Count
	// 20: CWE Flag Count
	// 21: Down/Up Ratio
	// 22: Init Fwd Win Bytes
	// 23: Init Bwd Win Bytes
	// 24: Active Mean
	// 25: Active Std
	// 26: Idle Std

	features.Protocol = parseInt(0)
	features.FlowDuration = int64(parseInt(1))
	features.TotalFwdPackets = parseInt(2)
	features.TotalBackwardPackets = parseInt(3)
	features.FwdPacketsLengthTotal = parseFloat(4)
	features.FwdPacketLengthMax = parseFloat(5)
	features.FwdPacketLengthMin = parseFloat(6)
	features.FwdPacketLengthStd = parseFloat(7)
	features.BwdPacketLengthMax = parseFloat(8)
	features.BwdPacketLengthMin = parseFloat(9)
	features.FlowIATMean = parseFloat(10)
	features.FlowIATMin = parseFloat(11)
	features.BwdIATMean = parseFloat(12)
	features.BwdIATMin = parseFloat(13)
	features.FwdPSHFlags = parseInt(14)
	features.FwdHeaderLength = parseInt(15)
	features.BwdHeaderLength = parseInt(16)
	features.BwdPacketsPerSecond = parseFloat(17)
	features.SYNFlagCount = parseInt(18)
	features.URGFlagCount = parseInt(19)
	features.CWEFlagCount = parseInt(20)
	features.DownUpRatio = parseFloat(21)
	features.InitFwdWinBytes = parseInt(22)
	features.InitBwdWinBytes = parseInt(23)
	features.ActiveMean = parseFloat(24)
	features.ActiveStd = parseFloat(25)
	features.IdleStd = parseFloat(26)

	return features
}
